package com.siyoumi.app.modules.account.service;

import com.siyoumi.app.entity.SysStore;
import com.siyoumi.app.modules.account.vo.VaAccount;
import com.siyoumi.app.modules.account.vo.VaChangeStore;
import com.siyoumi.app.modules.user.service.SvcSysUser;
import com.siyoumi.app.sys.entity.AesKi;
import com.siyoumi.app.sys.service.AdminService;
import com.siyoumi.app.sys.vo.ApprVo;
import com.siyoumi.app.modules.account.vo.VoAdminLogin;
import com.siyoumi.component.XApp;
import com.siyoumi.component.http.InputData;
import com.siyoumi.component.http.XHttpContext;
import com.siyoumi.config.SysConfig;
import com.siyoumi.entity.SysAccount;
import com.siyoumi.entity.SysAccsuperConfig;
import com.siyoumi.entity.SysAppRouter;
import com.siyoumi.entity.base.SysAccountBase;
import com.siyoumi.exception.EnumSys;
import com.siyoumi.mybatispuls.JoinWrapperPlus;
import com.siyoumi.service.SysAccountService;
import com.siyoumi.service.SysAppRouterService;
import com.siyoumi.service.SysAppService;
import com.siyoumi.component.XSpringContext;
import com.siyoumi.util.XDate;
import com.siyoumi.util.XReturn;
import com.siyoumi.util.XStr;
import com.siyoumi.validator.XValidator;
import lombok.SneakyThrows;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class SvcAccount {
    static public SvcAccount getBean() {
        return XSpringContext.getBean(SvcAccount.class);
    }

    static public SysAccountService getApp() {
        return XSpringContext.getBean(SysAccountService.class);
    }

    public List<Map<String, Object>> getList(String type) {
        String[] select = {
                "acc_id",
                "acc_name",
        };
        JoinWrapperPlus<SysAccount> query = listQuery();
        query.eq("acc_role", type)
                .select(select);
        return getApp().getMaps(query);
    }

    public SysAccount getEntityByPhone(String phone) {
        JoinWrapperPlus<SysAccount> query = getApp().join();
        query.eq(SysAccountBase.F.acc_x_id, XHttpContext.getX())
                .eq("acc_phone", phone);

        return getApp().first(query);
    }

    /**
     * 获取角色可设置的权限列表
     */
    public List<ApprVo> listSetRoleApprVo() {
        SysAccountService appAcc = SysAccountService.getBean();
        SysAccount entityAcc = appAcc.getSysAccountByToken();

        SysAppRouterService app = SysAppRouterService.getBean();
        List<String> appIds = SysAppService.getBean().getAppIds(entityAcc, true);
        //
        List<String> passIds = notSetAppIds();
        List<String> appIdNew = appIds.stream().filter(appId -> {
            return !passIds.contains(appId);
        }).collect(Collectors.toList());

        List<SysAppRouter> listAppr = app.getList(appIdNew, null);
        return XSpringContext.getBean(AdminService.class).appRouterToApprVo(listAppr);
    }

    /**
     * 不能设置的应用ID
     */
    protected static List<String> notSetAppIds() {
        List<String> apps = new ArrayList<>();
        apps.add("setting");
        apps.add("pwd");
        apps.add("app_admin");
        apps.add("sys_log");
        apps.add("account");
        return apps;
    }


    public JoinWrapperPlus<SysAccount> listQuery() {
        return listQuery(InputData.getIns());
    }

    public JoinWrapperPlus<SysAccount> listQuery(InputData inputData) {
        String name = inputData.input("name");

        JoinWrapperPlus<SysAccount> query = SysAccountService.getBean().join();
        query.eq("acc_x_id", XHttpContext.getX())
                .eq("acc_del", 0);
        //排序
        query.orderByDesc("acc_create_date")
                .orderByDesc("acc_id");
        if (XStr.hasAnyText(name)) { //名称
            query.like("acc_name", name);
        }

        return query;
    }

    public XReturn edit(InputData inputData, VaAccount vo) {
        List<String> ignoreField = new ArrayList<>();
        if (inputData.isAdminEdit()) {
            ignoreField.add("acc_x_id");
            //ignoreField.add("acc_role");
            ignoreField.add("acc_pwd");
        } else {
            vo.setAcc_pwd(XApp.encPwd(XHttpContext.getX(), "123456"));
        }

        return XApp.getTransaction().execute(status -> {
            XReturn r = SvcAccount.getApp().saveEntity(inputData, vo, true, ignoreField);

            return r;
        });
    }


    /**
     * 删除
     */
    @SneakyThrows
    @Transactional(propagation = Propagation.MANDATORY)
    public XReturn delete(List<String> ids) {
        XReturn r = XReturn.getR(0);

        JoinWrapperPlus<SysAccount> query = listQuery();
        query.eq(SysAccount.tableKey(), ids)
                .eq("acc_x_id", XHttpContext.getX());
        List<SysAccount> listAcc = getApp().get(query);
        for (SysAccount entityAcc : listAcc) {
            SysAccount entityUpdate = new SysAccount();
            entityUpdate.setAcc_id(entityAcc.getKey());
            entityUpdate.setAcc_del(XDate.toS());
            entityUpdate.setAcc_uid(XDate.toS().toString());
            if (XStr.hasAnyText(entityAcc.getAcc_phone())) {
                entityUpdate.setAcc_phone(entityAcc.getAcc_phone() + "|" + XDate.toS());
            }
            getApp().updateById(entityUpdate);
        }

        return r;
    }


    /**
     * 切换商家
     */
    public XReturn changeStore(VaChangeStore vo) {
        SysStore entityStore = SvcSysStore.getApp().getEntity(vo.getStore_id());
        XValidator.isNull(entityStore, "商家ID异常");

        if (!entityStore.getStore_acc_id().equals(vo.getAcc_id())) {
            return EnumSys.ERR_VAL.getR("帐号与商家不匹配");
        }

        SysAccount entityUpdate = new SysAccount();
        entityUpdate.setAcc_id(vo.getAcc_id());
        entityUpdate.setAcc_store_id(entityStore.getKey());
        getApp().updateById(entityUpdate);

        return EnumSys.OK.getR();
    }

    /**
     * 清空商家
     *
     * @param accId
     */
    public void clearStore(String accId) {
        if (XStr.isNullOrEmpty(accId)) {
            return;
        }

        SysAccount entity = getApp().getEntity(accId);
        if (entity == null) {
            return;
        }

        SysAccount entityUpdate = new SysAccount();
        entityUpdate.setAcc_id(entity.getKey());
        entityUpdate.setAcc_store_id("");
        getApp().saveOrUpdatePassEqualField(entity, entityUpdate);
    }

    /**
     * 帐号，商家信息
     *
     * @param entityAcc
     */
    public Map<String, Object> storeInfo(SysAccount entityAcc) {
        if (!SysAccountService.getBean().isStore(entityAcc)) {
            return null;
        }

        //商家列表
        List<Map<String, Object>> listStore = SvcSysStore.getBean().getList(entityAcc.getKey());

        Map<String, Object> mapStore = new HashMap<>();
        mapStore.put("list", listStore);

        if (!listStore.isEmpty()) { //获取当前商家信息
            String storeId = (String) listStore.get(0).get("store_id");
            if (XStr.isNullOrEmpty(entityAcc.getAcc_store_id())) { //无商家，切换第1个
                SvcAccount.getBean().changeStore(VaChangeStore.of(storeId, entityAcc.getAcc_id()));
            } else {
                storeId = entityAcc.getAcc_store_id();
            }

            String storeIdX = storeId;
            Map<String, Object> storeInfo = listStore.stream().filter(item -> item.get("store_id").equals(storeIdX)).findFirst().orElse(null);
            if (storeInfo == null) {
                SvcAccount.getBean().changeStore(VaChangeStore.of((String) listStore.get(0).get("store_id"), entityAcc.getAcc_id()));
            }
            mapStore.put("info", storeInfo); //当前商家
        }

        return mapStore;
    }

    /**
     * 登陆后台
     *
     * @param vo
     */
    public XReturn adminLogin(VoAdminLogin vo) {
        SysAccsuperConfig entityConfig = XHttpContext.getXConfig();
        AesKi aesKi = AesKi.of(entityConfig.getAconfig_token());
        String phone = aesKi.decTxt(vo.getPhone(), false);
        if (XStr.isNullOrEmpty(phone)) {
            return EnumSys.ERR_VAL.getR("手机号非法");
        }

        SysAccount entityAcc = getEntityByPhone(phone);
        if (entityAcc == null) {
            return EnumSys.ERR_VAL.getR("手机号没有权限");
        }
        if (!"store".equals(entityAcc.getAcc_role())) {
            return EnumSys.ERR_VAL.getR("账号非商家权限");
        }

        String token = AdminService.getBean().getToken(entityAcc, "wxapp");
        XReturn r = XReturn.getR(0);
        r.setData("admin_token", token);
        return r;
    }
}
